# Untitled - By: Admin - Wed Sep 25 2024
'''
梦飞OpenMV带UI界面应用程序，梦飞固件程序最好升级到6.5.5使用
主菜单程序说明：
1、存入根目录的程序，会自动在主界面刷新出来。同时会加载，位于ICONS文件夹中的同名BMP图片，作为图标。
2、通过按键逐一选择应用程序，选中的图标会变大，长按进入程序运行
3、在运行的程序内部也有按键检测机制，若要回到主界面也是长按按键，释放后回到主界面。
QQ群：718304823
淘宝店铺：
'''
import sensor, image, time,lcd
import pyb
from time import sleep
from os import listdir
from math import floor,ceil
from gc import collect
from button import BUTTON
from findpyfile import FINDPYFILE

#screen库，用于支持不同分辨率的屏幕驱动配置
#button库，用于按键驱动
#homepage库，用于显示UI主界面
#全局变量声明，uihomepage内部已经初始化了这些全局变量，后面直接用就行
global click_timer                           #按键计时
global py_file_quantity,py_file_names        #根文件参数
global img_homepage,icon_W                   #主界面
global select,last_select
icon_W=60
icon_H=12
icon_N=2

lcd.init()
lcd.set_direction(2)
button=BUTTON()  #声明按键，梦飞openmv只有一个按键，因此直接内部指定了按键
pyfile=FINDPYFILE() #声明文件搜索，初始化时已经搜索更新了，下面直接使用其内部元素
py_file_quantity=pyfile.py_file_quantity
py_file_names=pyfile.py_file_names
#img_homepage = sensor.alloc_extra_fb(icon_W*3+40,ceil(py_file_quantity/3)*icon_H,sensor.RGB565)##完整主页画布，画布尺寸是每行显示三个图标，按多行排列的方式计算
img_homepage = sensor.alloc_extra_fb(120,60,sensor.RGB565)##主页画布


def draw_homepage():
    global icon_N,icon_W,icon_H
    img_homepage.clear()
    #绘制主界面，没法封装成函数，不知道为啥
    for n in range(py_file_quantity):
        #绘制文件名
        img_homepage.draw_string(int(n%icon_N)*icon_W,int(n/icon_N)*icon_H,py_file_names[n],scale=1.0,x_spacing=1,mono_space=False,color=(139,0,255))
        img_homepage.draw_string(20,36,'mengfei GUI',scale=1.0,x_spacing=1,mono_space=False,color=(139,0,255))
        #exec('img_homepage.draw_rectangle(n*40,y*10,40,12,color=(255,0,0))')
#绘制图标函数
#在画布上绘制图标，输入图标（程序）序号、尺寸（0~100）
def draw_icon(n,last):
    global img_homepage
    try:
        #img_homepage.draw_string(4,4,"APP select:",color=(150,150,150),fill=True)
        img_homepage.draw_rectangle(int(last%icon_N)*icon_W,int(last/icon_N)*icon_H,icon_W,icon_H,color=(0,0,0),fill=True)#擦除文本部分
        img_homepage.draw_string(int(last%icon_N)*icon_W,int(last/icon_N)*icon_H,py_file_names[last],scale=1.0,x_spacing=1,mono_space=False,color=(139,0,255))
        img_homepage.draw_rectangle(int(n%icon_N)*icon_W,int(n/icon_N)*icon_H,icon_W,icon_H,color=(255,0,0))
    except:
        pass

draw_homepage()
draw_icon(1,1) #初始状态选中1，尺寸100
lcd.display(img_homepage)

def pyselect():
    global last_select,select
    button.key_event=0 #按键事件清空
    #while button.state():  pass #等待按键抬起
    click_timer=time.ticks() #重新开始计时
    while True:
        button.event()
        if button.state():
            while button.state():  pass #等待按键抬起
            if time.ticks()-click_timer>2000:#长按选中当前目标超过2s
                break
            if time.ticks()-click_timer<300:
                select=select+1
                if select >= py_file_quantity:  select=0 #光标重新开始
                if select!=last_select: #如果光标改变，则更新界面图标
                    draw_icon(select,last_select)
                    last_select=select
                    lcd.display(img_homepage)
        else:
            click_timer=time.ticks() #重新计时
    while button.state():  pass #等待按键抬起
    try:#打开所选中的程序
        print('exec start:/'+str(py_file_names[select]))
        collect()
        lcd.clear()
        exec_file=open('/%s.py'%str(py_file_names[select])).read()
        exec(exec_file)#在主程序中运行另一个py程序,并等待其运行结束
        del exec_file  #结束后删除并释放运行资源
        print('exec end:/'+str(py_file_names[select]))
    except Exception as err:
        img_homepage.clear()
        img_homepage.draw_string(0,20,'ERR:'+str(err),scale=1.0,x_spacing=1,mono_space=False,color=(139,0,255))
        lcd.display(img_homepage)
        print('ERR:'+str(err)) #报错
        while not button.state():  pass #等待按键按下
    while button.state():  pass #等待按键抬起
    lcd.clear()
    draw_homepage()
    draw_icon(select,last_select) #运行完退出还是从select的图标开始往后
    lcd.display(img_homepage)

select=1            #主页当前所选的程序序号
last_select=1       #上一次选择的程序序号
click_timer=time.ticks()#开始计时
while True:
    #按下左键先判断
    if button.state():
        pyselect()#程序框选，等待退出
    else:
        click_timer=time.ticks()#按键抬起，计时更新
